
#include <iostream>
#include "Client.h"
#include <pthread.h>
#include <vector>
#include "FileClient.h"
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <sstream>

using namespace std;

#include "muscle/message/Message.h"

using namespace muscle;




int main(int argc, char* argv[]){
	int port = atoi(argv[1]);

	string machine = argv[2];
	Client* temp = new Client("tcp", 4);

	temp->Connect(machine, port);

	FileClient fc = FileClient(temp);
	
	cout<<"Connection Established. Please choose an option below"<<endl;
	cout<<"1) Open file for reading"<<endl;
	cout<<"2) Open file for writing"<<endl;
	cout<<"3) Close file"<<endl;
	cout<<"4) Write to open file"<<endl;
	cout<<"5) Read from open file"<<endl;
	cout<<"6) Search for file"<<endl;
	cout<<"7) Delete file"<<endl;
	cout<<"8) List files on server"<<endl;
	cout<<"9) Run Stress Test (TC9)"<<endl;
	cout<<"0) Disconnect and close"<<endl;
	
	int choice;
	string var;
	string name;

	while(true){
		
		cin>>choice;
		int bytesread;
		switch (choice){
	case 1:
		int create1;
		cout<<"Filename: ";
		cin>>name;
		cout<<"Create new file?(1 or 0) ";
		cin>>create1;
		if (create1==1|| create1==0)
		fc.Open((char*)name.c_str(), 1, create1);
		break;
		
	case 2:
		int create2;
		cout<<"Filename: ";
		cin>>name;
		cout<<"Create new file?(1 or 0) ";
		cin>>create2;
		if (create2==1|| create2==0)
		fc.Open((char*)name.c_str(), 2, create2);
		break;
		
	case 3:
		cout<<"Filename: ";
		cin>>name;
		fc.Close((char*)name.c_str());
		break;
	
	case 4:	{
		string contents;
		int bytes;
		cout<<"File to write to: ";
		cin>> name;
		cout<<"Text to write to file: "<<endl;
		cin.ignore();
		getline(cin,contents);
		fc.Write((char*)name.c_str(), (char*)contents.c_str(), contents.size());
		break;
		}

	case 5:
		cout<<"File to read from: ";
		cin>> name;
		cout<<"Number of bytes to read: ";
		int length;
		length = 0;
		cin>> length;
		char ReadBuffer[10000];
		bytesread= fc.Read((char*)name.c_str(), length, ReadBuffer);
		cout.write(ReadBuffer, bytesread);
		cout << endl;
		cout.flush();
		break;


	case 6:
		cout<<"File to find: ";
		cin>> name;
		fc.Exists((char*)name.c_str());
		break;

	case 7:
		cout<<"File to delete: ";
		cin>> name;
		fc.Delete((char*)name.c_str());
		break;
	
	case 8:
		fc.List();
		break;

	case 9:
		{//BEGIN STRESS TEST
			char largedata[5000];//allocate a large data buffer 
			for(int i=0; i<5000; i++){
				largedata[i] = i%256;	//fill it with stuff
			}
			char name[123];
			cout<< "name of stress test file:" << endl;
			cin>> name;

			for(int j = 0; j<1000; j++)
			{//do this 1000 times

				fc.Open(name, 2, 1);//create a file
				fc.Write(name, largedata, 5000);
				char checkbuf[5000];
				fc.Close(name);
				int numRead;
				fc.Open(name, 1, 0);//open it back up
				numRead = fc.Read(name, 5000, checkbuf);
				if(numRead != 5000){
					cout << "Data size mismatch\n";
					break;
				}
				if(memcmp(largedata, checkbuf, 5000) != 0){
					cout << "Data mismatch\n";
					break;
				}
				fc.Delete(name);
			}
			break;
		}
	case 10:
		{//write 12 files
			for(int i = 0; i<12; i++)
			{//do this 12 times
			stringstream namebuilder;
			namebuilder << "TC6_" << i;
			string fname = namebuilder.str();
				fc.Open((char*)fname.c_str(), 2, 1);
			string data;
			stringstream databuilder;
			for(int j =0; j<=i; j++)
			{
				databuilder << "data ";
			}
			data = databuilder.str();
				fc.Write((char*)fname.c_str(), (char*)data.c_str(), data.size());
				fc.Close((char*)fname.c_str());
			}
		fc.List();
		}
		break;

	case 0:
		fc.Exit();
		break;

	default:
		cout<<"Not a valid command."<<endl;
		break;
	}
		cin.clear();
	//delete temp;
}
};
